﻿using Mapster;
using Microsoft.AspNetCore.Mvc;
using PARK.CardAcct.Entitys;
using PARK.ClayObject;
using PARK.Common.Configuration;
using PARK.Common.Core.Manager;
using PARK.Common.Enum;
using PARK.Common.Extension;
using PARK.Common.Filter;
using PARK.Common.Helper;
using PARK.Common.Model.NPOI;
using PARK.Consumer.Entity;
using PARK.Consumer.Entitys.Dto.ConsumMachine;
using PARK.Consumer.Entitys.Dto.ConsumRecharge;
using PARK.Consumer.Interfaces.ConsumRecharge;
using PARK.DataEncryption;
using PARK.Dependency;
using PARK.DynamicApiController;
using PARK.FriendlyException;
using PARK.JsonSerialization;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace PARK.Consumer
{
    /// <summary>
    /// 充值管理服务
    /// </summary>
    [ApiDescriptionSettings(Tag = "Consum", Name = "ConsumRecharge", Order = 200)]
    [Route("api/consum/[controller]")]
    public class ConsumRechargeService : IConsumRechargeService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<ConsumRechargeEntity> _consumRechargeRepository;
        private readonly SqlSugarScope _db;
        private readonly IUserManager _userManager;

        /// <summary>
        /// 初始化一个<see cref="ConsumRechargeService"/>类型的新实例
        /// </summary>
        public ConsumRechargeService(
            ISqlSugarRepository<ConsumRechargeEntity> consumRechargeRepository,
            IUserManager userManager)
        {
            _consumRechargeRepository = consumRechargeRepository;
            _db = _consumRechargeRepository.Context;
            _userManager = userManager;
        }
        /// <summary>
        /// 获取充值管理
        /// </summary>
        /// <param name="id">参数</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<dynamic> GetInfo(string id)
        {
            var entity = await _db.Queryable<ConsumRechargeEntity>().FirstAsync(p => p.Id == id);
            var output = entity.Adapt<ConsumRechargeInfoOutput>();
            output.createDate = Convert.ToDateTime(entity.CreateDate).ToString("yyyy-MM-dd HH:mm:ss");
            return output;
        }
        /// <summary>
		/// 获取充值管理列表
		/// </summary>
		/// <param name="input">请求参数</param>
		/// <returns></returns>
        [HttpGet("")]
        public async Task<dynamic> GetList([FromQuery] ConsumRechargeListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            if (userInfo != null && userInfo.UserAdminFlag != 2 && !string.IsNullOrEmpty(userInfo.companyId))
            {
                var sidx = input.sidx == null ? "billDate" : input.sidx;
                List<string> queryBillDate = input.billDate != null ? input.billDate.Split(',').ToObeject<List<string>>() : null;
                DateTime? startBillDate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.First()) : null;
                DateTime? endBillDate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.Last()) : null;
                var data = await _db.Queryable<ConsumRechargeEntity>()
                    .Where(p => p.CompanyId.Equals(userInfo.companyId) && p.IsPay==1)//权限
                    .WhereIF(!string.IsNullOrEmpty(input.billCode), p => p.BillCode.Contains(input.billCode))
                    .WhereIF(queryBillDate != null, p => p.BillDate >= new DateTime(startBillDate.ToDate().Year, startBillDate.ToDate().Month, startBillDate.ToDate().Day, 0, 0, 0))
                    .WhereIF(queryBillDate != null, p => p.BillDate <= new DateTime(endBillDate.ToDate().Year, endBillDate.ToDate().Month, endBillDate.ToDate().Day, 23, 59, 59))
                    .WhereIF(!string.IsNullOrEmpty(input.isImpairment), p => p.IsImpairment.Equals(input.isImpairment))
                    .WhereIF(!string.IsNullOrEmpty(input.paytype), p => p.Paytype.Equals(input.paytype))
                    .WhereIF(!string.IsNullOrEmpty(input.isPay), p => p.IsPay.Equals(input.isPay))
                    .WhereIF(!string.IsNullOrEmpty(input.keyword), p => p.JobNo.Contains(input.keyword) || p.ReallName.Contains(input.keyword) || p.CardNo.Contains(input.keyword))
                    .WhereIF(!string.IsNullOrEmpty(input.cardNo), p => p.CardNo.Equals(input.cardNo))
                    .WhereIF(!string.IsNullOrEmpty(input.userId),p=> p.CreateUser.Equals(input.userId))
                    .Select(cre => new ConsumRechargeListOutput
                    {
                        id = cre.Id,
                        billCode = cre.BillCode,
                        billDate = cre.BillDate,
                        rechargeAmt = cre.RechargeAmt,
                        isImpairment = cre.IsImpairment,
                        paytype = cre.Paytype,
                        isPay = cre.IsPay,
                        cardNo = cre.CardNo,
                        catCardNo =cre.CatCardNo,
                        departName = cre.DepartName,
                        reallName = cre.ReallName,
                        jobNo = cre.JobNo,
                        mobilePhone = cre.MobilePhone,
                        beforeRecharg = cre.BeforeRecharg,
                        afterRecharg = cre.AfterRecharg,
                        payDate = Convert.ToDateTime(cre.PayDate).ToString("yyyy-MM-dd HH:mm:ss"),
                        apiPayId = cre.ApiPayId,
                        summary = cre.Summary,
                        createUser= cre.CreateUser,
                        createUserName =cre.CreateUserName,
                        IsTake = cre.IsTake
                    }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
                return PageResult<ConsumRechargeListOutput>.SqlSugarPageResult(data);
            }
            else
                return null;
        }

        /// <summary>
        /// 获取平台充值管理列表
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [HttpGet("GetAllRechargeList")]
        public async Task<dynamic> GetAllRechargeList([FromQuery] ConsumRechargeListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var sidx = input.sidx == null ? "billDate" : input.sidx;
            List<string> queryBillDate = input.billDate != null ? input.billDate.Split(',').ToObeject<List<string>>() : null;
            DateTime? startBillDate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.First()) : null;
            DateTime? endBillDate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.Last()) : null;
            var data = await _db.Queryable<ConsumRechargeEntity>()
                .WhereIF(!string.IsNullOrEmpty(input.billCode), p => p.BillCode.Contains(input.billCode))
                .WhereIF(queryBillDate != null, p => p.BillDate >= new DateTime(startBillDate.ToDate().Year, startBillDate.ToDate().Month, startBillDate.ToDate().Day, 0, 0, 0))
                .WhereIF(queryBillDate != null, p => p.BillDate <= new DateTime(endBillDate.ToDate().Year, endBillDate.ToDate().Month, endBillDate.ToDate().Day, 23, 59, 59))
                .WhereIF(!string.IsNullOrEmpty(input.isImpairment), p => p.IsImpairment.Equals(input.isImpairment))
                .WhereIF(!string.IsNullOrEmpty(input.paytype), p => p.Paytype.Equals(input.paytype))
                .WhereIF(!string.IsNullOrEmpty(input.isPay), p => p.IsPay.Equals(input.isPay))
                .WhereIF(!string.IsNullOrEmpty(input.keyword), p => p.JobNo.Contains(input.keyword) || p.ReallName.Contains(input.keyword) || p.CardNo.Contains(input.keyword) || p.CatCardNo.Contains(input.keyword))
                .WhereIF(!string.IsNullOrEmpty(input.cardNo), p => p.CardNo.Equals(input.cardNo))
                .WhereIF(!string.IsNullOrEmpty(input.id), p => p.CompanyId.Equals(input.id))
                .Select(cre => new ConsumRechargeListOutput
                {
                    id = cre.Id,
                    billCode = cre.BillCode,
                    billDate = cre.BillDate,
                    rechargeAmt = cre.RechargeAmt,
                    isImpairment = cre.IsImpairment,
                    paytype = cre.Paytype,
                    isPay = cre.IsPay,
                    cardNo = cre.CardNo,
                    catCardNo = cre.CatCardNo,
                    departName = cre.DepartName,
                    reallName = cre.ReallName,
                    jobNo = cre.JobNo,
                    mobilePhone = cre.MobilePhone,
                    beforeRecharg = cre.BeforeRecharg,
                    afterRecharg = cre.AfterRecharg,
                    payDate = Convert.ToDateTime(cre.PayDate).ToString("yyyy-MM-dd HH:mm:ss"),
                    apiPayId = cre.ApiPayId,
                    summary = cre.Summary,
                    createUser = cre.CreateUser,
                    createUserName = cre.CreateUserName
                }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
            return PageResult<ConsumRechargeListOutput>.SqlSugarPageResult(data);
        }

        /// <summary>
        /// 新建充值管理
        /// </summary>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPost("")]
        public async Task Create([FromBody] ConsumRechargeCrInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            if (userInfo != null && userInfo.UserAdminFlag != 2 && !string.IsNullOrEmpty(userInfo.companyId))
            {
                _db.BeginTran();
                var emp = _db.Queryable<EmployeeEntity>().Where(e => e.DeleteMark != 1 && e.CardNo.Equals(input.cardNo) && e.CompanyId== userInfo.companyId).ToList().FirstOrDefault();
                if (emp == null)
                {
                    throw PARKException.Oh(ErrorCode.COM1011);
                }
                var entity = input.Adapt<ConsumRechargeEntity>();
                var list = _db.Queryable<ConsumRechargeEntity>().Where(d => d.CreateDate.Value.ToString("yyyy-MM-dd").Equals(DateTime.Now.ToString("yyyy-MM-dd"))).ToList();
                string num = "";
                if (list != null && list.Count > 0)
                {
                    num = (list.Count + 1).ToString();
                }
                else
                {
                    num = "1";
                }
                num = num.PadLeft(5, '0');
                entity.BillCode = "CZ" + DateTime.Now.ToString("yyyyMMdd") + num;
                entity.Id = YitIdHelper.NextId().ToString();
                entity.CardNo = emp.CardNo;
                entity.CatCardNo = emp.CatCardNo;
                entity.EmployeeId = emp.EmployeeId;
                entity.DepartId = emp.DepartId;
                entity.DepartName = emp.DepartName;
                entity.ReallName = emp.RealName;
                entity.JobNo = emp.JobNum;
                entity.MobilePhone = emp.MobilePhone;
                entity.BillDate = entity.PayDate = entity.DbDate = entity.CreateDate = DateTime.Now;
                entity.CreateUser = _userManager.User.Id;
                entity.CreateUserName = _userManager.User.RealName;
                entity.BeforeRecharg = emp.RechargeBalance; //充值前余额
                entity.AfterRecharg = emp.RechargeBalance + (entity.RechargeAmt * entity.IsImpairment); //充值后余额
                emp.RechargeBalance = entity.AfterRecharg;
                emp.LastUpdateTime = entity.BillDate;
                entity.CompanyId = userInfo.companyId;
                entity.CompanyName = userInfo.companyName;
                await _db.Updateable(emp).UpdateColumns(e => new { e.RechargeBalance, e.LastUpdateTime }).ExecuteCommandAsync();
                var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
                _db.CommitTran();
                if (!(isOk > 0)) throw PARKException.Oh(ErrorCode.COM1000);
            }
            else
                throw PARKException.Bah("您的权限无法操作!");
        }

        #region 导出充值记录Excel
        /// <summary>
        /// 获取考勤记录无分页列表
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [NonAction]
        public async Task<dynamic> GetNoPagingList([FromQuery] ConsumRechargeListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var sidx = input.sidx == null ? "billDate" : input.sidx;
            List<string> queryBillDate = input.billDate != null ? input.billDate.Split(',').ToObeject<List<string>>() : null;
            DateTime? startBillDate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.First()) : null;
            DateTime? endBillDate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.Last()) : null;
            var data = await _db.Queryable<ConsumRechargeEntity>()
                .Where(p => p.CompanyId.Equals(userInfo.companyId) && p.IsPay == 1)//权限
                .WhereIF(!string.IsNullOrEmpty(input.billCode), p => p.BillCode.Contains(input.billCode))
                .WhereIF(queryBillDate != null, p => p.BillDate >= new DateTime(startBillDate.ToDate().Year, startBillDate.ToDate().Month, startBillDate.ToDate().Day, 0, 0, 0))
                .WhereIF(queryBillDate != null, p => p.BillDate <= new DateTime(endBillDate.ToDate().Year, endBillDate.ToDate().Month, endBillDate.ToDate().Day, 23, 59, 59))
                .WhereIF(!string.IsNullOrEmpty(input.isImpairment), p => p.IsImpairment.Equals(input.isImpairment))
                .WhereIF(!string.IsNullOrEmpty(input.paytype), p => p.Paytype.Equals(input.paytype))
                .WhereIF(!string.IsNullOrEmpty(input.isPay), p => p.IsPay.Equals(input.isPay))
                .WhereIF(!string.IsNullOrEmpty(input.keyword), p => p.JobNo.Contains(input.keyword) || p.ReallName.Contains(input.keyword) || p.CardNo.Contains(input.keyword) || p.CatCardNo.Contains(input.keyword))
                .WhereIF(!string.IsNullOrEmpty(input.cardNo), p => p.CardNo.Equals(input.cardNo))
                .WhereIF(!string.IsNullOrEmpty(input.userId), p => p.CreateUser.Equals(input.userId))
                .Select(cre => new ConsumRechargeListOutput
                {
                    id = cre.Id,
                    billCode = cre.BillCode,
                    billDate = cre.BillDate,
                    rechargeAmt = cre.RechargeAmt,
                    isImpairment = cre.IsImpairment,
                    paytype = cre.Paytype,
                    isPay = cre.IsPay,
                    cardNo = cre.CardNo,
                    catCardNo = cre.CatCardNo,
                    departName = cre.DepartName,
                    reallName = cre.ReallName,
                    jobNo = cre.JobNo,
                    mobilePhone = cre.MobilePhone,
                    beforeRecharg = cre.BeforeRecharg,
                    afterRecharg = cre.AfterRecharg,
                    payDate = Convert.ToDateTime(cre.PayDate).ToString("yyyy-MM-dd HH:mm:ss"),
                    apiPayId = cre.ApiPayId,
                    summary = cre.Summary,
                    createUser = cre.CreateUser,
                    createUserName = cre.CreateUserName
                }).MergeTable().OrderBy(sidx + " " + input.sort).ToListAsync();
            return data;

        }

        /// <summary>
        /// 导出发放记录
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [HttpGet("Actions/Export")]
        public async Task<dynamic> Export([FromQuery] ConsumRechargeListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var exportData = new List<ConsumRechargeListOutput>();
            var exportDataNew = new List<ConsumRechargeListOutput>();

            var entity = input.Adapt<ConsumRechargeEntity>();

            if (input.dataType == 0)
            {
                var data = Clay.Object(await this.GetList(input));
                exportData = data.Solidify<PageResult<ConsumRechargeListOutput>>().list;
            }
            else
            {
                exportData = await this.GetNoPagingList(input);
            }

            foreach (ConsumRechargeListOutput item in exportData)
            {
                exportDataNew.Add(item);
            }

            List<ParamsModel> paramList = "[{\"value\":\"单据编号\",\"field\":\"billCode\"},{\"value\":\"单据日期\",\"field\":\"billDate\"},{\"value\":\"充值卡号\",\"field\":\"cardNo\"},{\"value\":\"卡面卡号\",\"field\":\"catCardNo\"},{\"value\":\"工号\",\"field\":\"jobNo\"},{\"value\":\"姓名\",\"field\":\"reallName\"},{\"value\":\"充值金额\",\"field\":\"rechargeAmt\"},{\"value\":\"类别\",\"field\":\"isImpairment\"},{\"value\":\"充值方式\",\"field\":\"paytype\"},{\"value\":\"充值时间\",\"field\":\"payDate\"},{\"value\":\"摘要\",\"field\":\"summary\"},]".ToList<ParamsModel>();
            ExcelConfig excelconfig = new ExcelConfig();
            excelconfig.FileName = userInfo.companyName + "_" + "充值记录_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";
            excelconfig.HeadFont = "微软雅黑";
            excelconfig.HeadPoint = 10;
            excelconfig.IsAllSizeColumn = true;
            excelconfig.ColumnModel = new List<ExcelColumnModel>();
            List<string> selectKeyList = input.selectKey.Split(',').ToList();
            foreach (var item in selectKeyList)
            {
                var isExist = paramList.Find(p => p.field == item);
                if (isExist != null)
                {
                    excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
                }
            }
            var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
            ExcelExportHelper<ConsumRechargeListOutput>.Export(exportDataNew, excelconfig, addPath);
            var fileName = _userManager.UserId + "|" + addPath + "|xls";
            var output = new
            {
                name = excelconfig.FileName,
                //url = "wwwroot/Resources/TemporaryFile/" + excelconfig.FileName
                url = "api/file/Download?encryption=" + DESCEncryption.Encrypt(fileName, "JNPF") //"wwwroot/Template/TemporaryFile/" + excelconfig.FileName //
            };
            return output;
        }
        #endregion
    }
}
